from django.db.models import Q
from rest_framework.decorators import action
from rest_framework.generics import ListAPIView
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from apps.headlines.models import Article, Channel
from apps.headlines.serializers.articlelist import ArticleListSerializer, ArticleAdd, ArticleDetailSerializer, \
    SearchForArticleSerializer, CommentPublicSerializer
from apps.headlines.utils import PageNum


class ArticleListView(ModelViewSet):
    """获取文章列表"""

    # 设置序列化器
    serializer_class = ArticleListSerializer
    # 获取数据
    queryset = Article.objects.all()
    # 分页
    pagination_class = PageNum

    # 新建文章
    def create(self, request, *args, **kwargs):
        try:
            # 获取用户
            user = request.user
        except Exception:
            # 否则为空
            user = None

        # 进行用户判断处理
        if user is not None and user.is_authenticated:
            # 获取请求参数
            request_parameter = request.data
            request_parameter["user"] = user.id
            serializer = ArticleAdd(data=request_parameter)
            serializer.is_valid(raise_exception=True)
            article = serializer.save()
            return Response({"success":True,"message":"发表成功","articleid":article.id})
        else:
            return Response({"success": False, "message": "未登录"},status=400)

    # 按频道获取文章列表
    @action(methods=['get'], detail=True, url_path="channel")
    def get_article(self,request,pk):
        if pk == "-1":
            article = self.get_queryset()
        else:
            channel1 = Channel.objects.get(id=pk)
            article = self.get_queryset().filter(channel=channel1)

        page = self.paginate_queryset(article)
        serializer = ArticleListSerializer(page,many=True)
        return Response({
            "count":12,
            "next":"http://52.83.143.113:8880/article/-1/channel/?page=2",
            "previous":"null",
            "results":serializer.data
        })

    # 根据频道ID获取文章详情信息
    def retrieve(self, request, *args, **kwargs):
        id = int(self.kwargs["pk"])
        article = Article.objects.get(id=id)
        serializer = ArticleDetailSerializer(article)
        return Response(serializer.data)

    # 收藏文章
    @action(methods=['put'], detail=True)
    def collect(self,request,pk):
        pk = int(pk)
        article = Article.objects.get(id=pk)
        if request.user.collected_articles.filter(id=pk):
            request.user.collected_articles.remove(article)
            return Response({'success': True, 'message': '取消收藏成功'})
        else:
            request.user.collected_articles.add(article)
            return Response({'success': True, 'message': '收藏成功'})

    # 给文章发表一条评论，给评论进行评论
    @action(methods=['post'], detail=True, url_path='publish_comment')
    def public_comment(self, request, pk):
        try:
            user = request.user
        except Exception:
            user = None
        # 判断用户是否登录
        if user is not None and user.is_authenticated:
            pk = int(pk)
            data1 = request.data
            article = Article.objects.get(id=pk)
            # 获取问题ID
            data1['article'] = pk
            # 获取用户ID
            data1['user'] = user.id
            # 通过序列化器获取data数据
            serializer = CommentPublicSerializer(data=data1)
            # 验证from表单，如果全部通过返回True，如果不通过则为False
            if serializer.is_valid():
                # 将数据保存
                serializer.save()

            return Response({
                'success': True,
                'message': '文章评论成功！'
            })
        else:
            return Response({'success': False, 'message': '用户未登录'}, status=400)


class SearchForArticle(ListAPIView):
    """根据关键字搜索文章列表"""

    # 获取Article查询集
    queryset = Article.objects.all()
    # 设置序列化器
    serializer_class = SearchForArticleSerializer
    # 分页
    pagination_class = PageNum

    # 重写方法
    def get_queryset(self):
        keyword = self.request.query_params.get("text")
        if keyword:
            return Article.objects.filter(Q(title__contains=keyword)|Q(content__contains=keyword))
        else:
            return Article.objects.all()